package org.centny.baccara;

import java.util.ArrayList;

import org.centny.bb.BaccaratBuilder;
import org.centny.bb.Gaming;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class BaccaraActivity extends Activity implements Gaming {
	Gaming.GRes gres = null;
	int scardIdx = 0;// showed card index.
	ArrayList<Byte> cards = new ArrayList<Byte>();
	ArrayList<ImageView> cimgs = new ArrayList<ImageView>();
	BaccaratBuilder baccarat = new BaccaratBuilder();
	Handler handler = new Handler();
	//
	int s_w, s_h;
	int c_w, c_h, c_y, c_mgn, c_dis;
	int player_money; // the player all money.
	float cardRate; // the card image H/W value.
	String player_name;
	float banker_rate = 0.95f;
	float player_rate = 1.0f;
	float tie_rate = 8.0f;
	float pair_rate = 11.0f;
	//
	RelativeLayout rl;
	TextView t_winner;
	View v_cover;
	TextView t_mplayer;
	TextView t_nplayer;
	ArrayList<Button> b_allf = new ArrayList<Button>();
	//
	int m_followed = 0;// player followed money.
	Button b_followed = null;// player selected follow button.

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_baccara);
		this.init();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_baccara, menu);
		return true;
	}

	private void init() {
		this.baccarat.setCardsCount(8);
		this.baccarat.follow(this);
		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		this.s_w = dm.widthPixels;
		this.s_h = dm.heightPixels;
		this.cardRate = Float.parseFloat(this.getResources().getString(
				R.string.g_card_rate));
		this.rl = (RelativeLayout) this.findViewById(R.id.gaming_rl);
		this.c_mgn = this.getResources().getDimensionPixelSize(
				R.dimen.g_c_margin);
		this.c_dis = this.getResources().getDimensionPixelSize(R.dimen.g_c_dis);
		this.c_w = (this.s_w - 2 * this.c_mgn - 6 * this.c_dis) / 6;
		this.c_h = (int) (this.cardRate * this.c_w);
		this.c_y = this.getResources().getDimensionPixelSize(R.dimen.g_c_y);
		this.t_winner = (TextView) this.findViewById(R.id.g_winner);
		this.t_nplayer = (TextView) this.findViewById(R.id.t_nplayer);
		this.v_cover = this.findViewById(R.id.v_cover);
		this.b_allf.add((Button) this.findViewById(R.id.b_fol_banker));
		this.b_allf.add((Button) this.findViewById(R.id.b_fol_player));
		this.b_allf.add((Button) this.findViewById(R.id.b_fol_tie));
		this.b_allf.add((Button) this.findViewById(R.id.b_fol_pair));
		this.player_money = 2130000;
		this.player_name = "Centny";
		this.t_mplayer = (TextView) this.findViewById(R.id.t_mplayer);
		this.t_nplayer.setText(this.player_name);

		//
		this.onSelGaming(null);
		this.showMPlayer();
	}

	public void showMPlayer() {
		this.t_mplayer.setText("" + this.player_money);
	}

	public void onClkStart(View v) {
		if (!(v instanceof Button)) {
			return;
		}
		Button btn = (Button) v;
		String btext = btn.getText().toString();
		if (btext.equals(this.getResources().getString(R.string.b_start))) {
			this.startGaming();
		}
	}

	public void onClkFolMoney(View t) {
		if (!(t instanceof Button)) {
			return;
		}
		if (this.b_followed == null) {
			return;
		}
		int f_c = Integer.parseInt(((Button) t).getText().toString());
		this.m_followed += f_c;
		this.player_money -= f_c;
		this.showMPlayer();
		this.onSelGaming(this.b_followed);
	}

	public void onClkClean(View t) {
		this.m_followed = 0;
		this.b_followed = null;
		this.onSelGaming(null);
	}

	public void onSelGaming(View t) {
		if (t != null) {
			this.b_followed = (Button) t;
		}
		for (Button b : this.b_allf) {
			if (b == t) {
				b.setBackgroundResource(R.color.b_fol_color);
			} else {
				b.setBackgroundResource(R.color.b_unfol_color);
			}
			b.setText(this.gamingName(b.getId(), b == t));
		}
	}

	private String gamingName(int id, Boolean selected) {
		String info = "";
		int rate = 0;
		switch (id) {
		case R.id.b_fol_banker:
			rate = (int) (this.banker_rate * 100);
			if (selected) {
				info = this.m_followed + " X Banker";
			} else {
				info = "Banker";
			}
			break;
		case R.id.b_fol_pair:
			rate = (int) (this.pair_rate * 100);
			if (selected) {
				info = this.m_followed + " X Pair";
			} else {
				info = "Pair";
			}
			break;
		case R.id.b_fol_player:
			rate = (int) (this.player_rate * 100);
			if (selected) {
				info = this.m_followed + " X Player";
			} else {
				info = "Player";
			}
			break;
		case R.id.b_fol_tie:
			rate = (int) (this.tie_rate * 100);
			if (selected) {
				info = this.m_followed + " X Tie";
			} else {
				info = "Tie";
			}
			break;
		}
		info += "(" + rate + "%)";
		return info;
	}

	private void startGaming() {
		if (this.m_followed < 1 || this.b_followed == null) {
			return;
		}
		this.clearCImgs();
		this.t_winner.setVisibility(View.INVISIBLE);
		this.rl.setVisibility(View.VISIBLE);
		this.v_cover.setVisibility(View.VISIBLE);
		this.baccarat.gaming();
	}

	private void endGaming() {
		AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f);
		alpha.setAnimationListener(new AnimationEndListener() {
			@Override
			public void onAnimationEnd(Animation animation) {
				rl.setVisibility(View.INVISIBLE);
				t_winner.setVisibility(View.INVISIBLE);
				v_cover.setVisibility(View.INVISIBLE);
				float mrate = 0;
				switch (gres.g) {
				case GOPT_BANK:
					if (b_followed.getId() == R.id.b_fol_banker) {
						mrate = 1 + banker_rate;
					}
					break;
				case GOPT_PLAY:
					if (b_followed.getId() == R.id.b_fol_player) {
						mrate = 1 + player_rate;
					}
					break;
				case GOPT_TIE:
					if (b_followed.getId() == R.id.b_fol_tie) {
						mrate = 1 + tie_rate;
					}
					break;
				}
				if (gres.paired && b_followed.getId() == R.id.b_fol_pair) {
					mrate = 1 + pair_rate;
				}
				player_money += m_followed * mrate;
				showMPlayer();
				onClkClean(null);
			}
		});
		alpha.setDuration(400);
		rl.startAnimation(alpha);
		t_winner.startAnimation(alpha);
	}

	private void nextGamingAnimation() {
		// if all cards showed,show winner.
		if (this.scardIdx >= this.cards.size()) {
			String wtext = "";
			switch (this.gres.g) {
			case GOPT_BANK:
				wtext = "Banker Winned";
				break;
			case GOPT_PLAY:
				wtext = "Player Winned";
				break;
			case GOPT_TIE:
				wtext = "Tie";
				break;
			}
			if (this.gres.paired) {
				wtext += "(Pair)";
			}
			this.t_winner.setText(wtext);
			this.t_winner.setVisibility(View.VISIBLE);
			AlphaAnimation alpha = new AlphaAnimation(0.1f, 1.0f);
			alpha.setAnimationListener(new AnimationEndListener() {
				@Override
				public void onAnimationEnd(Animation animation) {
					handler.postDelayed(hideGaming, 2000);
				}
			});
			alpha.setDuration(400);
			this.t_winner.startAnimation(alpha);
			return;
		}
		ImageView iv = new ImageView(this);
		Bitmap bmp = BitmapFactory.decodeResource(getResources(),
				Poker.card(this.cards.get(this.scardIdx)));
		iv.setImageBitmap(bmp);
		RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
				this.c_w, this.c_h);
		TranslateAnimation ta;
		int tax = 0;
		switch (this.scardIdx) {
		case 0:
			tax = (this.s_w / 2) - this.c_dis - this.c_w;
			break;
		case 1:
			tax = (this.s_w / 2) + this.c_dis;
			break;
		case 2:
			tax = (this.s_w / 2) - 2 * (this.c_dis + this.c_w);
			break;
		case 3:
			tax = (this.s_w / 2) + 2 * this.c_dis + this.c_w;
			break;
		case 4:
			tax = (this.s_w / 2) - 3 * (this.c_dis + this.c_w);
			break;
		case 5:
			tax = (this.s_w / 2) + 3 * this.c_dis + 2 * this.c_w;
			break;
		}
		this.scardIdx++;
		lp.setMargins(tax, this.c_y, 0, 0);
		iv.setLayoutParams(lp);
		ta = new TranslateAnimation(0, 0, -this.c_h - this.c_y, 0);
		ta.setDuration(600);
		ta.setAnimationListener(new AnimationEndListener() {
			@Override
			public void onAnimationEnd(Animation animation) {
				nextGamingAnimation();
			}
		});
		this.rl.addView(iv);
		this.cimgs.add(iv);
		iv.startAnimation(ta);
	}

	private Runnable hideGaming = new Runnable() {
		public void run() {
			endGaming();
		}
	};

	private void clearCImgs() {
		for (ImageView iv : this.cimgs) {
			this.rl.removeView(iv);
		}
		this.cimgs.clear();
	}

	@Override
	public void gaming(GRes res) {
		this.gres = res;
		this.cards.clear();
		this.scardIdx = 0;
		int p_s, b_s;
		p_s = this.gres.p_cards.size();
		b_s = this.gres.b_cards.size();
		if (p_s > b_s) {
			for (int i = 0; i < b_s; i++) {
				this.cards.add(this.gres.p_cards.get(i));
				this.cards.add(this.gres.b_cards.get(i));
			}
			this.cards.addAll(this.gres.p_cards.subList(b_s, p_s));
		} else {
			for (int i = 0; i < p_s; i++) {
				this.cards.add(this.gres.p_cards.get(i));
				this.cards.add(this.gres.b_cards.get(i));
			}
			this.cards.addAll(this.gres.b_cards.subList(p_s, b_s));
		}
		this.nextGamingAnimation();
	}

	public abstract class AnimationEndListener implements AnimationListener {
		@Override
		public void onAnimationRepeat(Animation animation) {
		}

		@Override
		public void onAnimationStart(Animation animation) {
		}
	}
}
